#ifdef a
//子类的拷贝构造函数
//派生类的拷贝构造函数必须调用基类中的拷贝构造函数进行由基类继承下来的成员的初始化
#include<iostream>
using namespace std;
class Base {
public:
	Base(int b = 10)
		:_b(b)
	{}

	
	//基类有，子类无，可执行(调用基类的拷贝构造函数，然后调用默认的拷贝构造函数)（实际是在子类的默认拷贝构造函数中调用基类拷贝构造函数的）
	/*
	Base(const Base& b) 
		:_b(b._b)
	{}
	*/

	//基类无，子类无，可运行

	
	Base(const Base& b)
		:_b(b._b)
	{}
	
public:
	int _b;
};

class Child : public Base
{
public:
	Child()
		//若只写了基类的拷贝构造而没有写基类的构造函数，则基类没有默认构造函数，需要显性定义
		:Base(10)
		,_c(100)
	{}

	/*
	//基类无，子类有，可执行，但子类中要调用基类拷贝构造函数,不调用也可执行，将调用基类的构造函数进行拷贝初始化
	Child(const Child& c)
//		:Base(c)//此处参数类型为Child,形参类型却为Base&->基类的引用可指向子类,值能访问_b,而不能访问子类中的_d
	:_c(c._c)
	{}
	*/

	/*
	//基类无，子类有，初始化列表中调用基类的默认构造函数，可执行，若不调用,则调用基类的构造函数进行拷贝初始化
	 Child(const Child & c)
		:Base(c)//此处参数类型为Child,形参类型却为Base&->基类的引用可指向子类
		,_c(c._c)
	{}
	*/

	/*
	//基类有，子类有，初始化列表调用基类拷贝构造，可执行;若不调用，则调用基类的构造函数而不是拷贝构造函数
	Child(const Child& c)
		//:Base(c)//此处参数类型为Child,形参类型却为Base&->基类的引用可指向子类
		:_c(c._c)
	{}
	*/

public:
	int _c;
};
int main() {
	Child d1;
	Child d2(d1);
	return 0;
}
//传参传子类，以基类引用接收(基类引用子类之后，能不能修改子类的个性成员)-》不可以？-->不可以

//（平时引用中，引用对象的值发生变化后，引用变量是否也随之发生变化）-》是？-->是


//注意，若在显性定义子类的拷贝构造函数时，其初始化列表中没有显性调用基类的拷贝构造函数，那么将通过基类的构造函数进行初始化，容易丢失信息
//造成由基类继承下来的成员拷贝发生错误

#endif


#ifdef a
#include<iostream>
using namespace std;
class Base {
public:
	Base(int b = 10)
		:_b(b)
	{}

	Base(const Base& b)
		:_b(b._b)
	{}

	int _b;
};

class Child : public Base
{
public:
	Child()
		:Base(10)
		,_c(20)
		,_p(new int[10])
	{}

	//子类中涉及资源管理，子类拷贝构造需要深拷贝
	/*
		//涉及资源管理不能使用memcpy,否则是浅拷贝
		
		Child(const Child& c) {
			int* temp = new int[10];
			memcpy(temp, c._p,sizeof(int) * 9);
			_p = temp;
			_c = c._c;
		}
	*/

	Child(const Child& c) 
		:Base(c)
		,_c(c._c)
	{
		int* temp = new int[10];
		for (size_t i = 0; i < 10; i++)
			temp[i] = c._p[i];
		_p = temp;
	}


	int* _p;
	int _c;

	~Child() {
		if (_p) {
			delete[] _p;
			_p = nullptr;
		}
	}
};
int main() {
	Child c1;
	c1._p[0] = 1;
	Child c2(c1);
	return 0;
}
//注意涉及资源管理时要显性定义拷贝构造函数，否则形成浅拷贝

//memcpy的复习

#endif
